import 'dart:math';
import 'learning_item.dart';
import 'user_preference.dart';

/// 推荐算法服务
class RecommendationService {
  static final Random _random = Random();

  /// 基于用户偏好推荐学习内容
  static List<LearningItem> recommendItems(
    List<LearningItem> allItems,
    UserPreference preference, {
    int count = 20, // 默认推荐数量
  }) {
    // 如果没有内容，直接返回空列表
    if (allItems.isEmpty) {
      return [];
    }

    // 计算每个项目的推荐分数
    final scoredItems = allItems.map((item) {
      final score = _calculateRecommendationScore(item, preference);
      return {'item': item, 'score': score};
    }).toList();

    // 按分数排序
    scoredItems.sort((a, b) => (b['score'] as double).compareTo(a['score'] as double));

    // 取前count个项目
    final recommendedItems = scoredItems.take(min(count, scoredItems.length)).map((e) {
      return e['item'] as LearningItem;
    }).toList();

    // 如果推荐数量不足，随机补充
    if (recommendedItems.length < count) {
      final remainingItems = allItems.where((item) => 
        !recommendedItems.any((recommended) => recommended.id == item.id)
      ).toList();
      
      remainingItems.shuffle(_random);
      final needed = count - recommendedItems.length;
      recommendedItems.addAll(remainingItems.take(min(needed, remainingItems.length)));
    }

    return recommendedItems;
  }

  /// 基于用户偏好推荐学习内容（排除已展示的项目）
  static List<LearningItem> recommendItemsWithExclusion(
    List<LearningItem> allItems,
    UserPreference preference,
    Set<String> excludedIds, {
    int count = 10, // 默认推荐数量
  }) {
    print('Recommend items with exclusion, allItems: ${allItems.length}, excluded: ${excludedIds.length}, count: $count');
    
    // 如果没有内容，直接返回空列表
    if (allItems.isEmpty) {
      print('No items available, returning empty list');
      return [];
    }

    // 过滤掉已展示的项目
    final availableItems = allItems.where((item) => !excludedIds.contains(item.id)).toList();
    print('Available items after exclusion: ${availableItems.length}');
    
    // 如果没有可用项目，尝试返回未排除的项目（防止无限循环）
    if (availableItems.isEmpty) {
      print('No available items after exclusion, returning random items from all items');
      final randomizedItems = List<LearningItem>.from(allItems);
      randomizedItems.shuffle(_random);
      return randomizedItems.take(min(count, randomizedItems.length)).toList();
    }

    // 计算每个项目的推荐分数
    final scoredItems = availableItems.map((item) {
      final score = _calculateRecommendationScore(item, preference);
      return {'item': item, 'score': score};
    }).toList();

    // 按分数排序
    scoredItems.sort((a, b) => (b['score'] as double).compareTo(a['score'] as double));

    // 取前count个项目
    final recommendedItems = scoredItems.take(min(count, scoredItems.length)).map((e) {
      return e['item'] as LearningItem;
    }).toList();

    // 如果推荐数量不足，随机补充
    if (recommendedItems.length < count) {
      final remainingItems = availableItems.where((item) => 
        !recommendedItems.any((recommended) => recommended.id == item.id)
      ).toList();
      
      remainingItems.shuffle(_random);
      final needed = count - recommendedItems.length;
      recommendedItems.addAll(remainingItems.take(min(needed, remainingItems.length)));
    }
    
    print('Recommended ${recommendedItems.length} items with exclusion');
    
    return recommendedItems;
  }

  /// 计算单个学习项目的推荐分数
  static double _calculateRecommendationScore(
    LearningItem item,
    UserPreference preference,
  ) {
    double score = 0.0;

    // 年级匹配度 (权重: 20%)
    if (preference.preferredGrade != null && preference.preferredGrade == item.grade) {
      score += 20.0;
    } else if (preference.preferredGrade != null) {
      // 年级越接近分数越高
      final gradeDifference = (preference.preferredGrade! - item.grade).abs();
      score += 20.0 * (1 - (gradeDifference / 12.0));
    }

    // 学科匹配度 (权重: 30%)
    if (preference.preferredSubject != null && preference.preferredSubject == item.subject) {
      score += 30.0;
    }

    // 学科兴趣度 (权重: 15%)
    if (preference.subjectInterests.containsKey(item.subject)) {
      final interest = preference.subjectInterests[item.subject] ?? 0;
      score += 15.0 * (interest / 100.0); // 假设兴趣度是0-100的值
    }

    // 模块匹配度 (权重: 20%)
    if (preference.preferredModule != null && preference.preferredModule == item.module) {
      score += 20.0;
    }

    // 模块兴趣度 (权重: 10%)
    if (preference.moduleInterests.containsKey(item.module)) {
      final interest = preference.moduleInterests[item.module] ?? 0;
      score += 10.0 * (interest / 100.0);
    }

    // 内容类型偏好 (权重: 5%)
    if (preference.typePreferences.containsKey(item.type)) {
      final preferenceValue = preference.typePreferences[item.type] ?? 0;
      score += 5.0 * (preferenceValue / 100.0);
    }

    // 随机因素 (权重: 0-5%，增加推荐的多样性)
    score += _random.nextDouble() * 5.0;

    return score;
  }

  /// 根据用户选择更新偏好
  static UserPreference updateUserPreference(
    UserPreference currentPreference,
    int? selectedGrade,
    String? selectedSubject,
    String? selectedModule,
  ) {
    return UserPreference(
      preferredGrade: selectedGrade ?? currentPreference.preferredGrade,
      preferredSubject: selectedSubject ?? currentPreference.preferredSubject,
      preferredModule: selectedModule ?? currentPreference.preferredModule,
      subjectInterests: currentPreference.subjectInterests,
      moduleInterests: currentPreference.moduleInterests,
      typePreferences: currentPreference.typePreferences,
    );
  }

  /// 根据用户交互更新偏好（例如喜欢某个内容）
  static UserPreference updatePreferenceBasedOnInteraction(
    UserPreference currentPreference,
    LearningItem item,
    bool isPositiveInteraction, // true表示喜欢，false表示不喜欢
  ) {
    var updatedPreference = currentPreference;
    
    // 增加/减少学科兴趣度
    final subjectInterestChange = isPositiveInteraction ? 5 : -5;
    final currentSubjectInterest = currentPreference.subjectInterests[item.subject] ?? 50;
    final newSubjectInterest = (currentSubjectInterest + subjectInterestChange)
        .clamp(0, 100); // 限制在0-100之间
    
    updatedPreference = updatedPreference.updateSubjectInterest(
      item.subject, 
      newSubjectInterest,
    );
    
    // 增加/减少模块兴趣度
    final moduleInterestChange = isPositiveInteraction ? 5 : -5;
    final currentModuleInterest = currentPreference.moduleInterests[item.module] ?? 50;
    final newModuleInterest = (currentModuleInterest + moduleInterestChange)
        .clamp(0, 100); // 限制在0-100之间
    
    updatedPreference = updatedPreference.updateModuleInterest(
      item.module, 
      newModuleInterest,
    );
    
    // 增加/减少内容类型偏好
    final typePreferenceChange = isPositiveInteraction ? 5 : -5;
    final currentTypePreference = currentPreference.typePreferences[item.type] ?? 50;
    final newTypePreference = (currentTypePreference + typePreferenceChange)
        .clamp(0, 100); // 限制在0-100之间
    
    updatedPreference = updatedPreference.updateTypePreference(
      item.type, 
      newTypePreference,
    );
    
    return updatedPreference;
  }
}